package com.fdb.efp.nls.service.impl;

import com.fdb.efp.nls.service.facade.FtpHandleService;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.SocketException;

@Service("ftpService")
public class FtpHandleServiceImpl implements FtpHandleService {
	private static Logger logger = LoggerFactory.getLogger(FtpHandleServiceImpl.class);
	/**
	 * 默认二进制方式传输
	 */
	private int fileType = FTP.BINARY_FILE_TYPE;
	/**
	 * ftpClient
	 */
	public FTPClient ftpClient = new FTPClient();

	@Value("${ftp.host}")
	private String host;
	@Value("${ftp.username}")
	private String username;
	@Value("${ftp.pwd}")
	private String pwd;
	@Value("ftp.file.remoteUploadPath")
	private String path;

	@Override
	public boolean uploadFile(String fileName, String newFileName) throws Exception {
		boolean result = false;
		try {
			if (ftpClient == null || !ftpClient.isConnected()) {
				logger.info("ftp未生效，重新连接:" + host);
				this.connect(host, 21, username, pwd);
			}
			logger.info("开始上传" + fileName);
			boolean isSuccess = this.upload(fileName, newFileName, path);
			logger.info("上传结束");
			if (isSuccess) {
				logger.info(fileName + "上传成功");
				ftpClient.disconnect();
				result = true;
			}
		} catch (IOException e) {
			logger.error("上传文件失败", e);
			throw new Exception("上传文件失败！:" + e);
		}
		return result;
	}

	@Override
	public boolean downLoadFile(String fileName, String filePath, String newFile) throws Exception {
		try {
			if (ftpClient == null || !ftpClient.isConnected()) {
				this.connect(host, 21, username, pwd);
			}
			ftpClient.changeWorkingDirectory(filePath);
			return download(fileName, newFile);
		} catch (Exception e) {
			logger.error("下载文件失败！");
			throw new Exception("下载文件失败！:" + e);
		}
	}

	@Override
	public String remoteAddFile(String fileName, String content) {
		try {
			logger.info("开始添加文件" + fileName);
			if (ftpClient == null || !ftpClient.isConnected()) {
				this.connect(host, 21, username, pwd);
			}
			if (createFile(fileName, content)) {
				logger.info("添加文件完成" + fileName);
				ftpClient.disconnect();
				return "";
			}
			;
		} catch (Exception e) {
			// e.printStackTrace();
			logger.error("添加文件异常" + e);
			return "添加文件异常" + e;
		}
		logger.error("添加文件异常");
		return "添加文件异常";
	}

	/**
	 * 远程读取文件
	 */
	@Override
	public String remoteRead(String fileName) {
		try {
			if (ftpClient == null || !ftpClient.isConnected()) {
				this.connect(host, 21, username, pwd);
			}
			ftpClient.changeWorkingDirectory(path);
			logger.info(fileName + "开始文件读取");
			FTPFile[] files = ftpClient.listFiles(fileName);
			if (files.length == 0) {
				logger.info(fileName + "文件不存在");
			} else {
				InputStream is = ftpClient.retrieveFileStream(fileName);
				String rstr = "";
				InputStreamReader isr = new InputStreamReader(is, "utf-8");
				BufferedReader br = new BufferedReader(isr);
				String readline;
				while ((readline = br.readLine()) != null) {
					rstr += readline;
				}
				br.close();
				isr.close();
				is.close();
				logger.info(fileName + "文件读取完成");
				return rstr;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 检查目标文件是否存在
	 */
	@Override
	public boolean isFileExists(String fileName) {
		try {
			if (ftpClient == null || !ftpClient.isConnected()) {
				this.connect(host, 21, username, pwd);
			}
			ftpClient.changeWorkingDirectory(path);
			logger.info("开始文件读取" + fileName);
			FTPFile[] files = ftpClient.listFiles(fileName);
			if (files.length == 0) {
				logger.info(fileName + "文件不存在");
			} else {
				logger.info(fileName + "文件存在");
				return true;
			}
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e.toString());
		}
		return false;
	}

	@Override
	public String remoteWrite(String fileName, String filePath, String appendContent) {
		return null;
	}

	@Override
	public String remoteDelete(String fileName, String filePath) {
		return null;
	}

	/**
	 * 连接FTP服务器
	 * 
	 * @param hostname
	 *            主机地址
	 * @param port
	 *            端口
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @param path
	 *            路径
	 * @return
	 * @throws SocketException
	 * @throws IOException
	 */
	public boolean connect(String hostname, int port, String username, String password, String path) throws SocketException, IOException {
		boolean flag = connect(hostname, port, username, password);
		if (flag) {
			// path必须是FTP当前目录下的子目录
			if (path.length() != 0) {
				flag = ftpClient.changeWorkingDirectory(path);
				return flag;
			}
		}
		return flag;
	}

	/**
	 * 连接FTP服务器
	 * 
	 * @param hostname
	 *            主机地址
	 * @param port
	 *            端口
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return
	 * @throws SocketException
	 * @throws IOException
	 */
	public boolean connect(String hostname, int port, String username, String password) throws SocketException, IOException {
		// 连接主机
		ftpClient.connect(hostname, port);
		ftpClient.setControlEncoding("GBK");
		// 判断是否完成握手，以便输入用户密码
		if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
			if (ftpClient.login(username, password)) {
				return true;
			}
		}
		disconnect();
		return false;
	}

	/**
	 * 二进制 FTP.BINARY_FILE_TYPE | ASCII FTP.ASCII_FILE_TYPE
	 * 
	 * @param fileType
	 * @throws IOException
	 */
	public void setFileType(int fileType) throws IOException {
		this.fileType = fileType;
		ftpClient.setFileType(this.fileType);
	}

	/**
	 * 关闭FTP连接
	 * 
	 * @throws IOException
	 */
	public void disconnect() throws IOException {
		if (ftpClient.isConnected()) {
			ftpClient.disconnect();
		}
	}

	/**
	 * 上传文件
	 * 
	 * @param fileName
	 *            本地文件全路径
	 * @param newName
	 *            新文件名
	 * @return
	 * @throws IOException
	 */
	public boolean upload(String fileName, String newName, String url) throws IOException {
		boolean flag = false;
		InputStream ins = null;
		try {
			ins = new FileInputStream(fileName);
			ftpClient.changeWorkingDirectory(url);
			flag = ftpClient.storeFile(newName, ins);
		} catch (IOException e) {
			flag = false;
			return flag;
		} finally {
			if (ins != null) {
				ins.close();
				ins = null;
			}
		}
		return flag;
	}

	/**
	 * 下载文件
	 * 
	 * @param remoteFileName
	 *            远程文件名字
	 * @param localFileName
	 *            本地文件名字 全路径
	 * @return
	 * @throws IOException
	 */
	public boolean download(String remoteFileName, String localFileName) throws IOException {
		boolean flag = false;
		OutputStream ous = null;
		try {
			FTPFile[] files = ftpClient.listFiles(remoteFileName);
			if (files.length == 0)
				throw new IOException(remoteFileName + "文件不存在");
			else {
				ous = new FileOutputStream(new File(localFileName));
				flag = ftpClient.retrieveFile(remoteFileName, ous);
			}

		} catch (IOException e) {
			flag = false;
			return flag;
		} finally {
			ftpClient.logout();
			if (ous != null) {
				ous.close();
				ous = null;
			}
		}
		return flag;
	}

	public boolean createFile(String fileName, String content) {
		InputStream is = null;
		// 1.输入流
		is = new ByteArrayInputStream(content.getBytes());
		try {
			ftpClient.storeFile(fileName, is);
			is.close();
		} catch (IOException e) {
			logger.error("输入流关闭出错!", e);
			return false;
		}
		return true;
	}

}
